#ifndef		__BLOBS_H_
#define		__BLOBS_H_

#include <d3d8.h>
#include "math3d.h"	

#pragma pack(4)
struct BLOBVERTEX
{
	he3d_CVector	v;
	he3d_CVector	n;
	DWORD			c;
};
#pragma pack()

#define BLOBFVF	D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE

class CBlob3D
{
public:

	// blob center position
	he3d_CVector	m_vPos;

	// blob properties
	DWORD			m_dwColor;
	DWORD			m_dwSign;
	FLOAT			m_fDensity;
	FLOAT			m_fRadius;	

	// calculate density at given point
	FLOAT BlobFunction( he3d_CVector& pos );		

	// constructor
	CBlob3D() : m_vPos(), m_dwColor( 0xffffff ), m_dwSign(FALSE), m_fDensity(1.0f), m_fRadius(1.0f)
	{
	}	
};

class CBlobSystem
{
private:

	class CNode
	{
	public:

		CBlob3D*		blob;
		CNode*			next;
		CNode*			prev;
	};

	// grid... one dimensional for easier allocation
	FLOAT*					m_pfGrid;
	LPWORD					m_pRow;
	LPWORD					m_pPlane;
	// grid properties
	DWORD					m_dwGridDensity;

	he3d_CVector			m_vSize;
	he3d_CVector			m_vCenter;		
	
	DWORD					m_bAutoResize;

	DWORD					m_dwBlobCount;
	CNode*					root;

	DWORD					m_dwVerticesCount;	
	DWORD					m_dwFacesCount;
	PDIRECT3DVERTEXBUFFER8	m_pvbVertices;
	PDIRECT3DINDEXBUFFER8	m_pibIndices;

	PDIRECT3DDEVICE8		m_pd3dDevice;	
	
	VOID ColorAndNormal( DWORD dwVertsCount, BLOBVERTEX* pVertTable, DWORD dwSign );	
	VOID ResizeToFit();

public:

	CBlobSystem( DWORD dwDensity = 32 );
	~CBlobSystem();	

	BOOL Initialize( PDIRECT3DDEVICE8 pDevice );

	VOID SetGridDensity( DWORD density );		
	VOID SetGridCenter( he3d_CVector& center );		

	DWORD GetGridDensity();		

	VOID AddBlob( CBlob3D* blob );
	VOID RemoveBlob( CBlob3D* blob );
	VOID RemoveBlob( DWORD index );
	CBlob3D* GetBlob( DWORD index );	
	DWORD GetBlobCount();

	// just recalculate blobs primitive and call render
	VOID CalculateDensity();	
	VOID Triangulate( PDIRECT3DVERTEXBUFFER8 vb, PDIRECT3DINDEXBUFFER8 ib, DWORD& dwVertsCount, DWORD& dwFacesCount, DWORD dwSign = FALSE );			
	VOID Render( PDIRECT3DDEVICE8 pDevice, DWORD dwSign );
};

#endif